﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Input;

namespace myBoard.Framework.MVVM
{
    /// <summary>
    /// A command whose sole purpose is to relay its functionality to other objects by
    /// invoking delegates. The default return value for the CanExecute method is 'true'.
    /// "Borrowed" from here:http://msdn.microsoft.com/en-us/magazine/dd419663.aspx
    /// </summary>
    public class RelayCommand : ICommand
    {
        private readonly Action<object> execute;
        private readonly Predicate<object> canExecute;

        /// <summary>
        /// Creates a new command that can always execute.
        /// </summary>
        public RelayCommand(Action<object> execute)
            : this(execute, null, null)
        {
        }

        /// <summary>
        /// Creates a new command.
        /// </summary>
        public RelayCommand(Action<object> execute, Predicate<object> canExecute)
            : this(execute, canExecute, null)
        {
        }

        /// <summary>
        /// Creates a new command.
        /// </summary>
        public RelayCommand(Action<object> execute, Predicate<object> canExecute, InputGesture inputBinding)
        {
            if (execute == null)
            {
                throw new ArgumentNullException("execute");
            }

            this.execute = execute;
            this.canExecute = canExecute;

            this.InputBindings = new InputBindingCollection();
            if (inputBinding != null) { this.InputBindings.Add(new InputBinding(this, inputBinding)); }
        }

        public event EventHandler CanExecuteChanged
        {
            add { CommandManager.RequerySuggested += value; }
            remove { CommandManager.RequerySuggested -= value; }
        }

        public bool CanExecute(object parameter)
        {
            return this.canExecute == null ? true : this.canExecute(parameter);
        }

        public void Execute(object parameter)
        {
            this.execute(parameter);
        }

        public InputBindingCollection InputBindings
        {
            get;
            private set;
        }
    }
}
